﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using Oscilloscope.Adjust;
using Oscilloscope.Channel;
using Oscilloscope.ChannelBuffer;
using Oscilloscope.Util;

namespace Oscilloscope.Curve
{
	// Token: 0x0200000A RID: 10
	internal abstract class SingleCurveGenerator : ICurveGenerator, IDisposable
	{
		// Token: 0x06000033 RID: 51 RVA: 0x0000418A File Offset: 0x0000238A
		public SingleCurveGenerator(IChannel channel)
		{
			if (channel == null)
			{
				throw new ArgumentNullException();
			}
			this.channel = channel;
			this.dataBufferIterator = ChannelBufferDataIteratorFactory.ChannelDataBufferIterator(this.channel.GetChannelBuffer().GetSignalType());
		}

		// Token: 0x06000034 RID: 52 RVA: 0x000041C0 File Offset: 0x000023C0
		public CurveVerPosIndicator[] GetCurveVerPosIndicators()
		{
			int height = this.channel.GetCanvasSize().Height;
			float num = (float)height / 2f;
			float yLocInCanvas = (float)((double)num - 
				(double)height * (this.channel.GetBaseLineValue() 
				/ (ValuePerCellAdjustGrade.Instance.GetValueOfGrade(this.channel.GetValuePerCellGrade()) * 8.0)));
            return new CurveVerPosIndicator[]
			{
				new CurveVerPosIndicator(yLocInCanvas, this.channel.GetChannelSN().ToString())
			};
		}

		// Token: 0x06000035 RID: 53 RVA: 0x00004248 File Offset: 0x00002448
		public Curve[] GetCurves()
		{
			return new Curve[]
			{
				new Curve(this.curveSegments, this.curveSegmentCount, this.curvePoints)
			};
		}

		/// <summary>
		/// 加载数据
		/// </summary>
		/// <param name="dataBuffer"></param>
		/// <param name="dataBufferValidCount"></param>
		/// <param name="dataBufferStartTime"></param>
		public void PrepareCurve(ChannelBufferData[] dataBuffer, int dataBufferValidCount, double dataBufferStartTime)
		{
			int width = this.channel.GetCanvasSize().Width;
			int height = this.channel.GetCanvasSize().Height;
			if (width <= 0 || height <= 0)
			{
				this.curveSegmentCount = 0;
				return;
			}
			double num;
			double num2;
			this.channel.GetTimeSpan(out num, out num2);
			double num3 = ValuePerCellAdjustGrade.Instance.GetValueOfGrade(this.channel.GetValuePerCellGrade()) * 8.0;
			float num4 = (float)((double)height * (this.channel.GetChannelBuffer().GetReferenceValue() / num3));
			float num5 = (float)((double)((float)height / 2f) - (double)height * (this.channel.GetBaseLineValue() / num3));
			double num6 = TimePerCellAdjustGrade.Instance.GetValueOfGrade(this.channel.GetTimePerCellGrade()) * 10.0;
			double num7 = 0.0;
			double num8 = 0.0;
			double num9 = 0.0;
			double num10 = 0.0;
			int num11 = 0;
			this.EnsureCurveBufferCapcity(num11);
			int num12 = 0;
			int num13 = 0;
			PointF[] array = new PointF[2];
			doublesSingle.Clear();
            this.dataBufferIterator.Initialize(dataBuffer, dataBufferValidCount, dataBufferStartTime, this.channel.GetChannelBuffer().GetTimeInterval(), 0);
			while (this.dataBufferIterator.Next(ref num7, ref num8))
			{
                // num7 是数据点的值
                // num8 是数据点的时间
                doublesSingle.Add(num7);
                //Console.WriteLine($"Value: {num7}, Time: {num8}");
                float num14 = (float)((double)width * ((num8 - num) / num6));
				float num15 = (float)((double)num4 - (double)height * (num7 / num3) + (double)num5);
				if (num14 >= 0f && num14 <= (float)width && num15 >= 0f && num15 <= (float)height)
				{
					PointF[] array2 = this.dataBufferIterator.SetNewPoint(num14, num15);
					if (array2 != null)
					{
						foreach (PointF pointF in array2)
						{
							this.EnsurePointBufferCapcity(num13 + num12);
							this.curvePoints[num13 + num12].X = pointF.X;
							this.curvePoints[num13 + num12].Y = pointF.Y;
							num12++;
						}
					}
				}
				else
				{
					PointF[] point = this.dataBufferIterator.GetPoint();
					if (point != null)
					{
						foreach (PointF pointF2 in point)
						{
							this.EnsurePointBufferCapcity(num13 + num12);
							this.curvePoints[num13 + num12].X = pointF2.X;
							this.curvePoints[num13 + num12].Y = pointF2.Y;
							num12++;
						}
					}
					if (num12 > 0)
					{
						int num16 = InternalUtils.InterpolationWithCanvas(new PointF(this.curvePoints[num13 + num12 - 1].X, this.curvePoints[num13 + num12 - 1].Y), new PointF(num14, num15), width, height, array);
						for (int k = 0; k < num16; k++)
						{
							this.EnsurePointBufferCapcity(num13 + num12);
							this.curvePoints[num13 + num12].X = array[k].X;
							this.curvePoints[num13 + num12].Y = array[k].Y;
							num12++;
						}
						this.curveSegments[num11].StartIndex = num13;
						this.curveSegments[num11].PointCount = num12;
						num11++;
						this.EnsureCurveBufferCapcity(num11);
						num13 += num12;
						num12 = 0;
					}
					else
					{
						bool flag = this.dataBufferIterator.PeekNext(ref num9, ref num10);
						if (flag)
						{
							float x = (float)((double)width * ((num10 - num) / num6));
							float y = (float)((double)num4 - (double)height * (num9 / num3) + (double)num5);
							int num16 = InternalUtils.InterpolationWithCanvas(new PointF(num14, num15), new PointF(x, y), width, height, array);
							if (num12 > 0)
							{
								for (int l = 0; l < num16; l++)
								{
									this.EnsurePointBufferCapcity(num13 + num12);
									this.curvePoints[num13 + num12].X = array[l].X;
									this.curvePoints[num13 + num12].Y = array[l].Y;
									num12++;
								}
								if (num16 > 0)
								{
									this.curveSegments[num11].StartIndex = num13;
									this.curveSegments[num11].PointCount = num12;
									num11++;
									this.EnsureCurveBufferCapcity(num11);
									num13 += num12;
									num12 = 0;
								}
							}
							else
							{
								for (int m = 0; m < num16; m++)
								{
									this.EnsurePointBufferCapcity(num13 + num12);
									this.curvePoints[num13 + num12].X = array[m].X;
									this.curvePoints[num13 + num12].Y = array[m].Y;
									num12++;
								}
								if (num16 >= 2)
								{
									this.curveSegments[num11].StartIndex = num13;
									this.curveSegments[num11].PointCount = num12;
									num11++;
									this.EnsureCurveBufferCapcity(num11);
									num13 += num12;
									num12 = 0;
								}
							}
						}
					}
				}
			}
			PointF[] point2 = this.dataBufferIterator.GetPoint();
			if (point2 != null)
			{
				foreach (PointF pointF3 in point2)
				{
					this.EnsurePointBufferCapcity(num13 + num12);
					this.curvePoints[num13 + num12].X = pointF3.X;
					this.curvePoints[num13 + num12].Y = pointF3.Y;
					num12++;
				}
			}
			if (num12 > 0)
			{
				this.curveSegments[num11].StartIndex = num13;
				this.curveSegments[num11].PointCount = num12;
				num11++;
				num13 += num12;
				num12 = 0;
			}
			this.curveSegmentCount = num11;
			this.PreviousCurveCount(num11);
			this.PreviousPointCount(num13 + num12);
		}

		// Token: 0x06000037 RID: 55 RVA: 0x000048D4 File Offset: 0x00002AD4
		protected void EnsureCurveBufferCapcity(int curveIndex)
		{
			if (this.curveSegments == null)
			{
				this.curveSegments = new CurveSegment[SingleCurveGenerator.CURVE_BUFFER_INC_STEP];
			}
			int num = this.curveSegments.Length;
			while (curveIndex >= num)
			{
				num += SingleCurveGenerator.CURVE_BUFFER_INC_STEP;
			}
			if (num != this.curveSegments.Length)
			{
				CurveSegment[] array = this.curveSegments;
				this.curveSegments = new CurveSegment[num];
				Array.Copy(array, this.curveSegments, array.Length);
				this.curveCountLessThanBufferCapcityCount = 0;
			}
		}

		// Token: 0x06000038 RID: 56 RVA: 0x00004944 File Offset: 0x00002B44
		protected void EnsurePointBufferCapcity(int pointIndex)
		{
			if (this.curvePoints == null)
			{
				this.curvePoints = new PointF[SingleCurveGenerator.POINT_BUFFER_INC_STEP];
			}
			int num = this.curvePoints.Length;
			while (pointIndex >= num)
			{
				num += SingleCurveGenerator.POINT_BUFFER_INC_STEP;
			}
			if (num != this.curvePoints.Length)
			{
				PointF[] array = this.curvePoints;
				this.curvePoints = new PointF[num];
				Array.Copy(array, this.curvePoints, array.Length);
				this.pointCountLessThanBufferCapcityCount = 0;
			}
		}

		// Token: 0x06000039 RID: 57 RVA: 0x000049B4 File Offset: 0x00002BB4
		protected void PreviousCurveCount(int previousCurveCount)
		{
			if (this.curveSegments == null)
			{
				return;
			}
			if (this.curveSegments.Length - SingleCurveGenerator.CURVE_BUFFER_DEC_STEP > previousCurveCount)
			{
				this.curveCountLessThanBufferCapcityCount++;
			}
			if (this.curveCountLessThanBufferCapcityCount >= SingleCurveGenerator.BUFFER_SIZE_ADJUST_THRESHOLD)
			{
				CurveSegment[] array = this.curveSegments;
				if (array.Length - SingleCurveGenerator.CURVE_BUFFER_DEC_STEP >= 0)
				{
					this.curveSegments = new CurveSegment[array.Length - SingleCurveGenerator.CURVE_BUFFER_DEC_STEP];
					Array.Copy(array, this.curveSegments, array.Length - SingleCurveGenerator.CURVE_BUFFER_DEC_STEP);
				}
				this.curveCountLessThanBufferCapcityCount = 0;
				GC.Collect();
			}
		}

		// Token: 0x0600003A RID: 58 RVA: 0x00004A40 File Offset: 0x00002C40
		protected void PreviousPointCount(int previousPointCount)
		{
			if (this.curvePoints == null)
			{
				return;
			}
			if (this.curvePoints.Length - SingleCurveGenerator.POINT_BUFFER_DEC_STEP > previousPointCount)
			{
				this.pointCountLessThanBufferCapcityCount++;
			}
			if (this.pointCountLessThanBufferCapcityCount >= SingleCurveGenerator.BUFFER_SIZE_ADJUST_THRESHOLD)
			{
				PointF[] array = this.curvePoints;
				this.curvePoints = new PointF[array.Length - SingleCurveGenerator.POINT_BUFFER_DEC_STEP];
				Array.Copy(array, this.curvePoints, array.Length - SingleCurveGenerator.POINT_BUFFER_DEC_STEP);
				this.pointCountLessThanBufferCapcityCount = 0;
				GC.Collect();
			}
		}

		// Token: 0x0600003B RID: 59 RVA: 0x00004ABE File Offset: 0x00002CBE
		public void Dispose()
		{
			this.curveSegments = null;
			this.curvePoints = null;
			this.channel = null;
			GC.Collect();
		}

		// Token: 0x04000014 RID: 20
		private static readonly int CURVE_BUFFER_INC_STEP = 500;

		// Token: 0x04000015 RID: 21
		private static readonly int CURVE_BUFFER_DEC_STEP = 100;

		// Token: 0x04000016 RID: 22
		private static readonly int POINT_BUFFER_INC_STEP = 5000;

		// Token: 0x04000017 RID: 23
		private static readonly int POINT_BUFFER_DEC_STEP = 1000;

		// Token: 0x04000018 RID: 24
		private int pointCountLessThanBufferCapcityCount;

		// Token: 0x04000019 RID: 25
		private int curveCountLessThanBufferCapcityCount;

		// Token: 0x0400001A RID: 26
		private static readonly int BUFFER_SIZE_ADJUST_THRESHOLD = 32;

		// Token: 0x0400001B RID: 27
		private CurveSegment[] curveSegments;

		// Token: 0x0400001C RID: 28
		private int curveSegmentCount;

		// Token: 0x0400001D RID: 29
		private PointF[] curvePoints;

		// Token: 0x0400001E RID: 30
		private IChannel channel;

		// Token: 0x0400001F RID: 31
		private IChannelBufferDataIterator dataBufferIterator;
        List<double> dSingle=new List<double>();
        public List<double> doublesSingle { get => dSingle;  }
    }
}
